package site.luojie.core.factory;

import site.luojie.core.bean.Bean;
import site.luojie.core.bean.BeanProperty;
import site.luojie.core.io.Resources;
import site.luojie.core.parse.XMLBeanParse;

import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description: bean创建工厂，生产对象(使用反射技术)
 * @Author jie.luo
 * @Create: 2020-05-01 00:28
 **/
public class BeanFactory {

    private BeanFactory() {
    }

    private static BeanFactory beanFactory = new BeanFactory();

    private static Map<String, Object> beanMap = new HashMap<>();

    static {
        InputStream resourceAsStream = Resources.getResourceAsStream("beans.xml");
        try {
            // 获取所有 bean
            List<Bean> beans = new XMLBeanParse().parse(resourceAsStream);
            // 所有Bean 下的 property
            List<BeanProperty> beanProperties = new ArrayList<>();

            for (Bean bean : beans) {
                Object o = Class.forName(bean.getClassName()).newInstance();
                beanMap.put(bean.getId(), o);

                beanProperties.addAll(bean.getBeanProperties());
            }

            if (beanProperties.size() > 0) {
                for (BeanProperty beanProperty : beanProperties) {
                    String parentId = beanProperty.getParentId();
                    String ref = beanProperty.getRef();

                    Object refObject = beanMap.get(ref);
                    Object parentObject = beanMap.get(parentId);

                    for (Method method : parentObject.getClass().getMethods()) {
                        if (method.getName().equals("set" + beanProperty.getTitleCaseName())) {
                            method.invoke(parentObject, refObject);
                        }
                    }
                    beanMap.put(parentId, parentObject);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static BeanFactory getInstance() {
        return beanFactory;
    }

    public Object getBean(String id) {
        return beanMap.get(id);
    }
}
